﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Text.RegularExpressions;
using System.IO;
using sqlDALgen.Renderers;
using codewriter.Renderers;

namespace sqlDALgen
{
    public class TemplateRenderer
    {
        private static readonly Regex _blanksReader = new Regex("({(.*?)})", RegexOptions.Compiled);

        private static IDictionary<String, Func<XmlNode, IRenderer>> _renderers = new Dictionary<String, Func<XmlNode, IRenderer>>();

        static TemplateRenderer()
        {
            Register("default", (n) => TextRenderer.Get(n));
            Register("text", (n) => TextRenderer.Get(n));
            Register("static", (n) => StaticRenderer.Get(n));
            Register("if", (n) => IfRenderer.Get(n));
            Register("loop", (n) => LoopRenderer.Get(n));
            Register("replace", (n) => ReplaceRenderer.Get(n));
            Register("script", (n) => ScriptRenderer.Get(n));
            Register("split", (n) => SplitRenderer.Get(n));
        }

        public static void Register(String text, Func<XmlNode, IRenderer> getter)
        {
            _renderers.Add(text, getter);
        }

        public static IRenderer Get(XmlNode node)
        {
            if (_renderers.ContainsKey(node.Name))
                return _renderers[node.Name](node);
            
            return _renderers["default"](node);
        }

        public static void Render(string template, TemplateData data, string outputFolder)
        {
            var reader = new XmlDocument();
            reader.Load(template);
            var outFolder = Path.Combine(outputFolder, "");

            var renderer = TemplateRenderer.Get(reader.FirstChild);
            var genValue = renderer.Render(data);

            var name = renderer.FileName;

            if (!Directory.Exists(outFolder)) Directory.CreateDirectory(outFolder);

            File.WriteAllText(Path.Combine(outFolder, name), genValue);
        }

        public static String RenderNodeText(XmlNode node, TemplateData data)
        {
            var builder = new StringBuilder();

            foreach (XmlNode subNode in node)
            {
                builder.Append(TemplateRenderer.Get(subNode).Render(data));
            }

            return builder.ToString();
        }

        public static String FillData(string template, TemplateData data)
        {
            Match match = null;
            while ((match = _blanksReader.Match(template)).Success)
            {
                var value = data.ResolvePath(match.Value.Substring(1, match.Value.Length - 2)).ToString();
                template = template.Replace(match.Value, value);
            }

            return template;
        }
    }
}